/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 * $LastChangedRevision$
 */

/** @file
 *
 * @defgroup app_scheduler Scheduler
 * @{
 * @ingroup ble_sdk_lib
 *
 * @brief The scheduler is used for transferring execution from the interrupt context to the main
 *        context.
 *
 * @details See @ref ble_sdk_apps_seq_diagrams for sequence diagrams illustrating the flow of events
 *          when using the Scheduler.
 *
 * @section app_scheduler_req Requirements:
 *
 * @subsection create_app_scheduler_cfg Creation of app_scheduler_cfg.h:
 *
 *   - Applications using the Scheduler must have a configuration file named
 *     app_scheduler_cfg.h (see @ref ble_sdk_apps_config_files for details).
 *
 * @subsection main_context_logic Logic in main context:
 *
 *   - Define an event handler for each type of event expected.
 *   - Initialise the scheduler by calling app_sched_init() function before entering the application
 *     main loop.
 *   - Call app_sched_schedule() from the main loop each time the application wakes up because of an
 *     event (typically when nrf_wait_for_app_event() returns).
 *
 * @subsection int_context_logic Logic in interrupt context:
 *
 *   - In the interrupt handler, call app_sched_event_put()
 *     with the appropriate data and event handler. This will insert an event into the
 *     scheduler's queue. The app_sched_schedule() function will pull this event and call its
 *     handler in the main context.
 *
 * For an example usage of the scheduler, please see the implementations of
 * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
 *
 * @image html scheduler_working.jpg The high level design of the scheduler
 */

#ifndef APP_SCHEDULER_H__
#define APP_SCHEDULER_H__

#include <stdint.h>
#include "app_timer.h"
#include "app_scheduler_cfg.h"

/**@brief Scheduler event handler type. */
typedef void (*app_sched_event_handler_t)(app_sched_event_data_t * p_app_sched_event_data);

/**@brief Initializes the Scheduler.
 *
 * @details This initializes the event queues. It must be called before entering the main loop.
 */
void app_sched_init(void);

/**@brief Executes all scheduled events.
 *
 * @details This function must be called from within the main loop. It will execute all
 *          events in all queues.
 */
void app_sched_schedule(void);

/**@brief Schedules an event.
 *
 * @details Puts an event into an event queue.
 *
 * @param[in]   p_data     Pointer to event structure to be sent.
 * @param[in]   handler    Event handler to receive the event.
 * @param[in]   queue_id   ID of the queue to put the event.
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
uint32_t app_sched_event_put(app_sched_event_data_t *  p_data,
                             app_sched_event_handler_t handler,
                             uint8_t                   queue_id);

/**@brief Schedules a timer event.
 *
 * @details Puts an timer event into the event queue. A pointer to this function is passed to
 *          app_sched_timers_init() to make the timer module pass timer events to the event
 *          scheduler.
 *
 * @param[in]   timer_id          Id of timer on which an event occurred.
 * @param[in]   timeout_handler   Application timeout handler.
 * @param[in]   priority          Priority level at which the timeout handler will be run. This will
 *                                be mapped directly to the scheduler queue_id. The highest priority
 *                                is 0, the second highest is 1 and so on.
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
uint32_t app_sched_timer_event_schedule(app_timer_id_t              timer_id,
                                        app_timer_timeout_handler_t timeout_handler,
                                        uint8_t                     priority);

#endif // APP_SCHEDULER_H__

/** @} */
